#!/bin/bash

#This script contains various dirty fixes to keep Pi-Apps running smoothly as it matures.
#It repairs mistakes that some apps have made, as well as fixing other system issues. Some apps have been removed or renamed.

#This script is executed by the updater script as well as the main Pi-Apps installation script.

#This script uses the 'runonce' function - it avoids running any of these fixes more than once.
#If a runonce entry is modified, then it will be run once more.

#Set DIRECTORY variable if necessary
if [ -z "$DIRECTORY" ];then
  DIRECTORY="$(readlink -f "$(dirname "$(dirname "$0")")")"
fi

#Get pi-apps api functions if necessary
if ! command -v runonce >/dev/null ;then
  set -a #make all functions in the api available to subprocesses
  source "${DIRECTORY}/api"
fi

#add ~/Desktop /opt /usr/local/bin and /usr/local/share/applications if not present
runonce <<"EOF"
  if [ -f "$HOME/Desktop" ]; then
    rm -f "$HOME/Desktop"
    mkdir -p "$HOME/Desktop" || exit 1
  elif [ ! -d "$HOME/Desktop" ]; then
    mkdir -p "$HOME/Desktop" || exit 1
  fi
  if [ ! -d /opt ]; then
    sudo_popup mkdir /opt || exit 1
  fi
  if [ ! -d /usr/local/bin ]; then
    sudo_popup mkdir -p /usr/local/bin || exit 1
  fi
  if [ ! -d /usr/local/share/applications ]; then
    sudo_popup mkdir -p /usr/local/share/applications || exit 1
  fi
  #Pi-Apps tries to avoid unnecessary reboots at all cost. desktop launchers can be installed to /usr/local/share/applications, which is often not searched by default if /usr/local/share did not exist on boot.
  #This path is added to $XDG_DATA_DIRS on the next reboot, but we don't want to wait for that!
  #If XDG_DATA_DIRS is missing /usr/local/share, then bind-mount /usr/local/share/applications to /usr/share/applications
  if [[ "$XDG_DATA_DIRS" != */usr/local/share* ]] && [ -z "$(ls /usr/share/applications/usr-local-temporary)" ];then
    sudo_popup mkdir -p /usr/share/applications/usr-local-temporary
    sudo_popup mount --bind /usr/local/share/applications /usr/share/applications/usr-local-temporary
  fi
EOF

#generate settings
runonce <<"EOF"
  if [ "$(ls "$DIRECTORY/data/settings" 2>/dev/null | wc -l)" -le 2 ];then
    "${DIRECTORY}/settings" refresh
  fi
EOF

#regenerate package-app status for one-time migration
runonce <<"EOF"
  IFS=$'\n'
  for app in $(list_apps package) ;do
    rm -f "${DIRECTORY}/data/status/${app}" || exit 1
  done
  
  refresh_all_pkgapp_status
EOF

# remove deprecated apps (only when running in a visible terminal)
case $(ps -o stat= -p $$) in
  *+*) # Running in foreground
runonce <<"EOF"
  #populate yadflags since array contents are not passed into runonce
  yadflags=(--class Pi-Apps --name "Pi-Apps" --center --window-icon="${DIRECTORY}/icons/logo.png" --title="Pi-Apps")
  #remove deprecated apps
  remove_deprecated_app "FreeCAD (precompiled)"
  remove_deprecated_app "Chromium Media Edition"
  remove_deprecated_app "Cordless"
  remove_deprecated_app "Retropie"
  remove_deprecated_app "Raspi2png"
  remove_deprecated_app "Falkon"
  remove_deprecated_app "FreeCAD"
  remove_deprecated_app "LinuxCNC"
  remove_deprecated_app "Steam" "32" "Due to upstream changes from Valve, Steam can no longer be used on 32bit OSs.
You can install Steam from Pi-Apps on a 64bit OS."
  remove_deprecated_app "Pale Moon" "32" "Upstream has stopped packaging Pale Moon for armhf and has removed all builds from their repos.
You can install Pale Moon from Pi-Apps on a 64bit OS."
  remove_deprecated_app "Cawbird"
  remove_deprecated_app "Email Checker"
  remove_deprecated_app "Pi-Apps Terminal Plugin (python)"
  remove_deprecated_app "Sysmon"
  remove_deprecated_app "BlockPi"
  remove_deprecated_app "TBOPlayer"
  remove_deprecated_app "Minecraft Java MultiMC5" "" "Due to upstream changes, MultiMC5 for ARM can no longer support any newer versions of Mincraft so it has been removed from Pi-Apps.
All users are encouraged to install Prism Launcher from Pi-Apps (a MultiMC fork with many improvements and new features)."
  remove_deprecated_app "Chromium Widevine" "" "Use the Better Chromium app to handle enabling/disabling of Widevine in Chromium."
  remove_deprecated_app "PiKISS GUI" "" "Due to upstream changes at piKiss this GUI is no longer relevant."
  remove_deprecated_app "piKiss" "" "This application developer is unwilling to fix and remove scripts that break users installs. It is unsafe to install piKiss scripts."
EOF
  ;;
esac

#remove old apps and migrate chromium downgrading apps to the new "Downgrade Chromium" app
runonce <<"EOF"
  #rework chromium downgrading apps to one single new app: 'Downgrade Chromium'
  rm -rf "${DIRECTORY}/apps/Back to Chromium v86"
  rm -rf "${DIRECTORY}/apps/Back to Chromium v78"
  if [ "$(cat "${DIRECTORY}/data/status/Back to Chromium v78" 2>/dev/null)" == installed ] || [ "$(cat "${DIRECTORY}/data/status/Back to Chromium v86" 2>/dev/null)" == installed ];then
    echo "installed" > "${DIRECTORY}/data/status/Downgrade Chromium"
  fi
  
  #rename 'Turbo Scratch' app to 'Turbowarp'
  rm -rf "${DIRECTORY}/apps/Turbo Scratch"
  mv -f "${DIRECTORY}/data/status/Turbo Scratch" "${DIRECTORY}/data/status/Turbowarp" 2>/dev/null
  
  #rename 'Pi-Apps Terminal Plugin' app to 'Pi-Apps Terminal Plugin (python)'
  rm -rf "${DIRECTORY}/apps/Pi-Apps Terminal Plugin"
  mv -f "${DIRECTORY}/data/status/Pi-Apps Terminal Plugin" "${DIRECTORY}/data/status/Pi-Apps Terminal Plugin (python)" 2>/dev/null
  
  #rename 'Whatsapp' app to 'WhatsApp'
  rm -rf "${DIRECTORY}/apps/Whatsapp"
  mv -f "${DIRECTORY}/data/status/Whatsapp" "${DIRECTORY}/data/status/WhatsApp" 2>/dev/null
  
  #rename 'Sonic Pi 3.2' to 'Sonic Pi'
  rm -rf "${DIRECTORY}/apps/Sonic Pi 3.2"
  mv -f "${DIRECTORY}/data/status/Sonic Pi 3.2" "${DIRECTORY}/data/status/Sonic Pi" 2>/dev/null
  
  
  #rename 'Min Browser' to 'Min'
  rm -rf "${DIRECTORY}/apps/Min Browser"
  mv -f "${DIRECTORY}/data/status/Min Browser" "${DIRECTORY}/data/status/Min" 2>/dev/null
  
  #rename 'Pale Moon Browser' to 'Pale Moon'
  rm -rf "${DIRECTORY}/apps/Pale Moon Browser"
  mv -f "${DIRECTORY}/data/status/Pale Moon Browser" "${DIRECTORY}/data/status/Pale Moon" 2>/dev/null
  
  #rename 'Puffin Browser Demo' to 'Puffin'
  rm -rf "${DIRECTORY}/apps/Puffin Browser Demo"
  mv -f "${DIRECTORY}/data/status/Puffin Browser Demo" "${DIRECTORY}/data/status/Puffin" 2>/dev/null
  
  #rename 'Quartz Browser' to 'Quartz'
  rm -rf "${DIRECTORY}/apps/Quartz Browser"
  mv -f "${DIRECTORY}/data/status/Quartz Browser" "${DIRECTORY}/data/status/Quartz" 2>/dev/null
  
  #rename 'Tor Browser' to 'Tor'
  rm -rf "${DIRECTORY}/apps/Tor Browser"
  mv -f "${DIRECTORY}/data/status/Tor Browser" "${DIRECTORY}/data/status/Tor" 2>/dev/null
  
  #rename 'KeePassX' to 'KeePassXC'
  rm -rf "${DIRECTORY}/apps/KeePassX"
  mv -f "${DIRECTORY}/data/status/KeePassX" "${DIRECTORY}/data/status/KeePassXC" 2>/dev/null

  #rename 'TeamViewer Host' to 'TeamViewer'
  if [ -f "${DIRECTORY}/data/status/TeamViewer Host" ] && [ $(cat "${DIRECTORY}/data/status/TeamViewer Host") == "installed" ]; then
    # installed
    rm -rf "${DIRECTORY}/apps/TeamViewer Host"  "${DIRECTORY}/apps/TeamViewer"
    mv -f "${DIRECTORY}/data/status/TeamViewer Host" "${DIRECTORY}/data/status/TeamViewer"
  else
    # not installed
    rm -rf "${DIRECTORY}/apps/TeamViewer Host"
  fi

  #rename 'Minecraft Java' to 'Minecraft Java Lunar'
  if [ -f "${DIRECTORY}/data/status/Minecraft Java" ] && [ $(cat "${DIRECTORY}/data/status/Minecraft Java") == "installed" ]; then
    # installed
    mv -f "${DIRECTORY}/data/status/Minecraft Java" "${DIRECTORY}/data/status/Minecraft Java Lunar"
    rm -rf "${DIRECTORY}/apps/Minecraft Java Lunar"
    mv -f "${DIRECTORY}/apps/Minecraft Java" "${DIRECTORY}/apps/Minecraft Java Lunar"
  else
    # not installed
    rm -rf "${DIRECTORY}/apps/Minecraft Java"
  fi
  
  #rename 'Brave Browser' to 'Brave'
  rm -rf "${DIRECTORY}/apps/Brave Browser"
  mv -f "${DIRECTORY}/data/status/Brave Browser" "${DIRECTORY}/data/status/Brave" 2>/dev/null
  
  #rename 'Discord' to 'Webcord'
  rm -rf "${DIRECTORY}/apps/Discord"
  mv -f "${DIRECTORY}/data/status/Discord" "${DIRECTORY}/data/status/Webcord" 2>/dev/null
  
  #rename 'Geekbench' to 'Geekbench 5'
  if [ -f "${DIRECTORY}/data/status/Geekbench" ] && [ $(cat "${DIRECTORY}/data/status/Geekbench") == "installed" ]; then
    # installed
    mv -f "${DIRECTORY}/data/status/Geekbench" "${DIRECTORY}/data/status/Geekbench 5"
    rm -rf "${DIRECTORY}/apps/Geekbench 5"
    mv -f "${DIRECTORY}/apps/Geekbench" "${DIRECTORY}/apps/Geekbench 5"
  else
    # not installed
    rm -rf "${DIRECTORY}/apps/Geekbench"
  fi
  true
EOF

#rename xlunch setting to xlunch-dark
runonce <<"EOF"
  if [ "$(cat "${DIRECTORY}/data/settings/App List Style")" == xlunch ];then
    echo 'xlunch-dark' > "${DIRECTORY}/data/settings/App List Style"
  fi
EOF

#transition from box86-no-binfmt-restart package to box86
runonce <<"EOF"
  if dpkg -l box86-no-binfmt-restart &>/dev/null ;then
    sudo_popup bash -c 'dpkg --remove box86-no-binfmt-restart'
    rm -f "${DIRECTORY}/data/status/Box86"
    "${DIRECTORY}/manage" uninstall Box86
    "${DIRECTORY}/manage" install Box86
  fi
  
  #if box86 is supposedly installed, but box86 command not found, reinstall box86
  if [ "$(app_status Box86)" == 'installed' ] && ! command -v box86 >/dev/null;then
    rm -f "${DIRECTORY}/data/status/Box86"
    "${DIRECTORY}/manage" uninstall Box86
    "${DIRECTORY}/manage" install Box86
  fi
  true
EOF

#remove files from pi-apps folder that are no longer used
runonce <<"EOF"
  rm -f "${DIRECTORY}/etc/bitlylink"
  rm -rf "${DIRECTORY}/data/categories"
EOF

#change settings icon
runonce <<"EOF"
  [ -a "$HOME/.local/share/applications/pi-apps-settings.desktop" ] && sed -i "s/logo.png/settings.png/g" "$HOME/.local/share/applications/pi-apps-settings.desktop" || true
EOF

#Raspbian Buster systems have a bug where XDG_DATA_DIRS is overwritten as the Raspberry Pi desktop is loaded.
#This fixes it, as PiOS maintainers are unwilling to.
#See: https://github.com/Botspot/pi-apps/issues/1833
runonce <<"EOF"
  if [ -f /usr/bin/startlxde-pi ] && grep -q '/var/lib/menu-xdg"' /usr/bin/startlxde-pi ;then
    sudo_popup sed -i 's;/var/lib/menu-xdg";/var/lib/menu-xdg${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}";g' /usr/bin/startlxde-pi
  fi
EOF

#Doom3 app by techcoder20 installed problematic SDL packages. (sdl2-image sdl2-mixer sdl2-ttf)
#Nothing else uses them, and they just cause problems with many other games, so remove them
runonce <<"EOF"
  if package_installed sdl2-image ;then
    list+='sdl2-image '
  fi
  if package_installed sdl2-mixer ;then
    list+='sdl2-mixer '
  fi
  if package_installed sdl2-ttf ;then
    list+='sdl2-ttf '
  fi
  
  if [ ! -z "$list" ]; then
    sudo_popup apt -y purge $list || exit 1
  fi
  true
EOF

#Fix PiKiss-GUI messing up folder permissions
runonce <<"EOF"
  if [ -d ~/.local/bin ] && [ "$(stat -c "%U %G" ~/.local/bin)" != "$USER $USER" ]; then
    sudo_popup chown $USER:$USER ~/.local/bin
  fi
EOF

#Fix PiKiss vulkan breaking apt install/uninstalls/upgrades
runonce <<"EOF"
  # bump to run again
  if [ -f /etc/apt/apt.conf.d/99reinstall-vulkan-driver-hook ]; then
    sudo_popup rm -f /etc/apt/apt.conf.d/99reinstall-vulkan-driver-hook
  fi
EOF

#remove old mcpi repositories
runonce <<"EOF"
  if [ -f /etc/apt/sources.list.d/Alvarito050506_mcpi-devs.list ];then
    sudo_popup rm -f /etc/apt/sources.list.d/Alvarito050506_mcpi-devs.list
  fi
  if [ -f /etc/apt/sources.list.d/mcpi-revival.list ];then
    sudo_popup rm -f /etc/apt/sources.list.d/mcpi-revival.list
    sudo_popup rm -f /etc/apt/trusted.gpg.d/mcpi-revival.gpg
  fi
EOF

#remove EOL Raspbian Addons repository
runonce <<"EOF"
  if [ -f /etc/apt/sources.list.d/rpirepo.list ];then
    sudo_popup rm -f /etc/apt/sources.list.d/rpirepo.list
    sudo_popup rm -f /usr/share/keyrings/raspbian-addons-archive-keyring.gpg
  fi
EOF

#remove old vivaldi repository
runonce <<"EOF"
  if [ -f /etc/apt/sources.list.d/vivaldi-archive.list ];then
    sudo_popup rm -f /etc/apt/sources.list.d/vivaldi-archive.list
    sudo_popup rm -f /usr/share/keyrings/vivaldi-browser.gpg
  fi
EOF

#update pi-apps .desktop icons
runonce <<"EOF"
#menu button

echo "Updating menu button..."
mkdir -p ~/.local/share/applications
if [ -f /etc/xdg/menus/lxde-pi-applications.menu ];then
echo "[Desktop Entry]
Name=Pi-Apps
Comment=Raspberry Pi App Store for open source projects
Exec=${DIRECTORY}/gui
Icon=${DIRECTORY}/icons/logo.png
Terminal=false
StartupWMClass=Pi-Apps
Type=Application
Categories=Utility
StartupNotify=true" > ~/.local/share/applications/pi-apps.desktop
else
echo "[Desktop Entry]
Name=Pi-Apps
Comment=Raspberry Pi App Store for open source projects
Exec=${DIRECTORY}/gui
Icon=${DIRECTORY}/icons/logo.png
Terminal=false
StartupWMClass=Pi-Apps
Type=Application
Categories=Utility;System;PackageManager;
StartupNotify=true" > ~/.local/share/applications/pi-apps.desktop
fi

chmod 755 ~/.local/share/applications/pi-apps.desktop
gio set ~/.local/share/applications/pi-apps.desktop "metadata::trusted" yes

#copy menu button to Desktop
mkdir -p ~/Desktop
cp -f ~/.local/share/applications/pi-apps.desktop ~/Desktop/

chmod 755 ~/Desktop/pi-apps.desktop
gio set ~/Desktop/pi-apps.desktop "metadata::trusted" yes

#copy icon to local icons directory (necessary on some wayland DEs like on PiOS Wayfire)
mkdir -p ~/.local/share/icons
cp -f ${DIRECTORY}/icons/logo.png ~/.local/share/icons/pi-apps.png
cp -f ${DIRECTORY}/icons/settings.png ~/.local/share/icons/pi-apps-settings.png

#settings menu button
echo "Updating Settings menu button..."
echo "[Desktop Entry]
Name=Pi-Apps Settings
Comment=Configure Pi-Apps or create an App
Exec=${DIRECTORY}/settings
Icon=${DIRECTORY}/icons/settings.png
Terminal=false
StartupWMClass=Pi-Apps-Settings
Type=Application
Categories=Settings;
StartupNotify=true" > ~/.local/share/applications/pi-apps-settings.desktop

echo "Updating autostarted updater..."
mkdir -p ~/.config/autostart
echo "[Desktop Entry]
Name=Pi-Apps Updater
Exec=${DIRECTORY}/updater onboot
Icon=${DIRECTORY}/icons/logo.png
Terminal=false
StartupWMClass=Pi-Apps
Type=Application
X-GNOME-Autostart-enabled=true
Hidden=false
NoDisplay=false" > ~/.config/autostart/pi-apps-updater.desktop

EOF

#Fix mimeapps containing only boxy svg mimeapp entry without [Added associations] appearing first
runonce <<"EOF"
  if [ "$(head -n1 ~/.config/mimeapps.list)" == 'image/svg+xml;application/illustrator=boxy-svg.desktop;' ];then
    #remove first line from mimeapps.list
    sed -i 1d ~/.config/mimeapps.list
    
    #Add it back correctly
    echo "[Added Associations]
image/svg+xml=boxy-svg.desktop;
application/illustrator=boxy-svg.desktop;" >> ~/.config/mimeapps.list
  fi
EOF

#correct home ownership of gnupg repo
runonce <<"EOF"
  if [ -d ~/.gnupg ] && stat -c "%U %G" ~/.gnupg/* | grep -q "root"; then
    sudo_popup chown -R $USER:$USER ~/.gnupg
  fi
EOF

#fix unintended wget-log pollution due to wget bug https://savannah.gnu.org/bugs/?51181
runonce <<"EOF"
  if ls ~/wget-log*; then
    sudo_popup rm -rf ~/wget-log*
  fi
EOF

#remove pi-apps dummy debs leftover from interrupted runs of package_install
runonce <<"EOF"
  find ~/ -maxdepth 1 | grep -xE "$HOME/pi-apps-[0-9a-z]{8}(.deb)?" | xargs rm -rf
EOF

#Install rpi-chromium-mods back from accidental chromium update-reinstall that did not add it back
runonce <<"EOF"
  #if rpi-chromium-mods is available, not installed, and was uninstalled on the affected dates, and the Chromium app was uninstalled and installed, install rpi-chromium-mods back.
  if package_available rpi-chromium-mods && ! package_installed rpi-chromium-mods && \
    grep ' not-installed rpi-chromium-mods' /var/log/dpkg.log | tail -1 | grep -q '2024-02-\(22\|23\|24\|25\|26\)' && \
    find "${DIRECTORY}"/logs | grep -qF 'uninstall-success-Chromium.log' && find "${DIRECTORY}"/logs | grep -qF 'install-success-Chromium.log';then
    
    #install rpi-chromium-mods back.
    apt_lock_wait
    sudo_popup apt install -y rpi-chromium-mods
  fi
EOF

#include DEBIAN_FRONTEND variable in sudo default environment if set
runonce <<"EOF"
  sudo_popup sh -c "cat > /etc/sudoers.d/debian_frontend << _EOF_
Defaults      env_keep += DEBIAN_FRONTEND
_EOF_"
EOF

true
